//package com.lopo.mybatis_auto_insert;
//
//import org.apache.ibatis.binding.MapperMethod;
//import org.apache.ibatis.builder.StaticSqlSource;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.mapping.ParameterMapping;
//import org.apache.ibatis.mapping.SqlCommandType;
//import org.apache.ibatis.mapping.SqlSource;
//import org.apache.ibatis.plugin.Interceptor;
//import org.apache.ibatis.plugin.Intercepts;
//import org.apache.ibatis.plugin.Invocation;
//import org.apache.ibatis.plugin.Signature;
//import org.springframework.stereotype.Component;
//import org.yangmy.tide.common.core.utils.BaseEntity;
//import org.yangmy.tide.common.security.SecurityUtils;
//
//import java.lang.reflect.Field;
//import java.time.LocalDateTime;
//import java.util.*;
//
///**
// * mybatis拦截器实现自动填充审计字段，原创
// * @author YangMingYang
// * @since 2022/5/10
// */
//@Component
//@Intercepts({@Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class})})
//public class IbatisAuditDataInterceptor implements Interceptor {
//
//    private final Set<String> cache=new HashSet<>();
//
//    @Override
//    public Object intercept(Invocation invocation) throws Throwable {
//        Object[] args = invocation.getArgs();
//        MappedStatement ms = (MappedStatement) args[0];
//        Object params=args[1];
//        SqlSource newSqlSource=null;
//        if (ms.getSqlCommandType()==SqlCommandType.INSERT) {
//            //重写sql语句增加审计字段
//            String sql=ms.getSqlSource().getBoundSql(null).getSql();
//            String newSql = insertAudit(sql);
//
//            //创建新的参数隐射
//            List<ParameterMapping> newParameterMappings=new ArrayList<>();
//            ParameterMapping createByMapping=new ParameterMapping.Builder(ms.getConfiguration(),"createBy",Object.class).build();
//            ParameterMapping createTimeMapping=new ParameterMapping.Builder(ms.getConfiguration(),"createTime",Object.class).build();
//            ParameterMapping updateByMapping=new ParameterMapping.Builder(ms.getConfiguration(),"updateBy",Object.class).build();
//            ParameterMapping updateTimeMapping=new ParameterMapping.Builder(ms.getConfiguration(),"updateTime",Object.class).build();
//            ParameterMapping delFlagMapping=new ParameterMapping.Builder(ms.getConfiguration(),"delFlag",Object.class).build();
//            newParameterMappings.add(createByMapping);
//            newParameterMappings.add(createTimeMapping);
//            newParameterMappings.add(updateByMapping);
//            newParameterMappings.add(updateTimeMapping);
//            newParameterMappings.add(delFlagMapping);
//            newParameterMappings.addAll(ms.getSqlSource().getBoundSql(null).getParameterMappings());
//
//            //创建新的SqlSource
//            newSqlSource=new StaticSqlSource(ms.getConfiguration(),newSql,newParameterMappings);
//
//            //填充审计字段
//            if(params instanceof BaseEntity){
//                BaseEntity baseEntity=(BaseEntity) params;
//                baseEntity.setCreateBy(Long.valueOf(Objects.requireNonNull(SecurityUtils.getUserId())));
//                baseEntity.setCreateTime(LocalDateTime.now());
//                baseEntity.setUpdateBy(Long.valueOf(Objects.requireNonNull(SecurityUtils.getUserId())));
//                baseEntity.setUpdateTime(LocalDateTime.now());
//                baseEntity.setDelFlag(0);
//            }else if(params instanceof MapperMethod.ParamMap){
//                MapperMethod.ParamMap<Object> map= (MapperMethod.ParamMap) params;
//                map.put("createBy",SecurityUtils.getUserId());
//                map.put("createTime",LocalDateTime.now());
//                map.put("updateBy",SecurityUtils.getUserId());
//                map.put("updateTime",LocalDateTime.now());
//                map.put("delFlag",0);
//            }
//
//            //修改sqlSource
//            if(!cache.contains(ms.getId())){
//                Field msField = invocation.getArgs()[0].getClass().getDeclaredField("sqlSource");
//                msField.setAccessible(true);
//                msField.set(invocation.getArgs()[0],newSqlSource);
//                cache.add(ms.getId());
//            }
//        }
//        if (ms.getSqlCommandType()==SqlCommandType.UPDATE) {
//            //重写sql语句增加审计字段
//            String source=ms.getSqlSource().getBoundSql(null).getSql();
//            String newSql=updateAudit(source);
//
//            //创建新的参数隐射
//            List<ParameterMapping> newParameterMappings=new ArrayList<>();
//            ParameterMapping updateByMapping=new ParameterMapping.Builder(ms.getConfiguration(),"updateBy",Object.class).build();
//            ParameterMapping updateTimeMapping=new ParameterMapping.Builder(ms.getConfiguration(),"updateTime",Object.class).build();
//            newParameterMappings.add(updateByMapping);
//            newParameterMappings.add(updateTimeMapping);
//            newParameterMappings.addAll(ms.getSqlSource().getBoundSql(null).getParameterMappings());
//
//            //创建新的SqlSource
//            newSqlSource=new StaticSqlSource(ms.getConfiguration(),newSql,newParameterMappings);
//
//            //填充审计字段
//            if(params instanceof BaseEntity){
//                BaseEntity baseEntity=(BaseEntity) params;
//                baseEntity.setUpdateBy(Long.valueOf(Objects.requireNonNull(SecurityUtils.getUserId())));
//                baseEntity.setUpdateTime(LocalDateTime.now());
//            }else{
//                MapperMethod.ParamMap<Object> map= (MapperMethod.ParamMap) params;
//                map.put("updateBy",SecurityUtils.getUserId());
//                map.put("updateTime",LocalDateTime.now());
//            }
//
//            //修改sqlSource
//            if(!cache.contains(ms.getId())){
//                Field msField = invocation.getArgs()[0].getClass().getDeclaredField("sqlSource");
//                msField.setAccessible(true);
//                msField.set(invocation.getArgs()[0],newSqlSource);
//                cache.add(ms.getId());
//            }
//        }
//
//        //修改参数值
//        invocation.getArgs()[1]=params;
//        return invocation.proceed();
//    }
//
//    public String insertAudit(String source){
//        char[] chars = source.toCharArray();
//        StringBuilder newSql=new StringBuilder();
//        boolean afterFormalParam=false;
//        for (char c : chars) {
//            String cStr=String.valueOf(c);
//            newSql.append(cStr);
//            if (cStr.equals("(")){
//                if(afterFormalParam){
//                    newSql.append("?,?,?,?,?,");
//                }else {
//                    newSql.append("create_by,create_time,update_by,update_time,del_flag,");
//                }
//            }
//            if(cStr.equals(")")){
//                afterFormalParam=true;
//            }
//        }
//        return newSql.toString();
//    }
//
//    public String updateAudit(String source){
//        String[] strArray = source.split("\\s+");
//        StringBuilder newSql=new StringBuilder();
//        boolean afterSet=false;
//        for (String s : strArray) {
//            if(afterSet){
//                s="update_by=?,update_time=?,"+s;
//                afterSet=false;
//            }
//            if(s.equals("set")||s.equals("SET")){
//                afterSet=true;
//            }
//            newSql.append(s).append(" ");
//        }
//        return newSql.toString();
//    }
//
//}
//
